package com.piggy.logi.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.piggy.common.core.exception.GlobalException;
import com.piggy.common.satoken.utils.SecurityUtils;
import com.piggy.logi.sys.bo.LogiSysWaybillConfigEditBo;
import com.piggy.logi.sys.domain.LogiSysAgentPayConfig;
import com.piggy.logi.sys.domain.LogiSysGoodsInsureConfig;
import com.piggy.logi.sys.domain.LogiSysWaybillConfig;
import com.piggy.logi.sys.domain.LogiWaybill;
import com.piggy.logi.sys.mapper.LogiSysWaybillConfigMapper;
import com.piggy.logi.sys.service.*;
import com.piggy.logi.sys.vo.LogiSysWaybillConfigVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 基础业务设置Service业务层处理
 *
 * @author fengxy
 * @date 2023/10/17 21:54
 **/
@Slf4j
@Service
public class LogiSysWaybillConfigServiceImpl extends ServiceImpl<LogiSysWaybillConfigMapper, LogiSysWaybillConfig> implements ILogiSysWaybillConfigService {

    @Resource
    private ILogiWaybillService logiWaybillService;

    @Resource
    private ILogiSysAgentPayConfigService logiSysAgentPayConfigService;

    @Resource
    private ILogiSysGoodsInsureConfigService logiSysGoodsInsureConfigService;

    @Resource
    private ILogiSysOrderSetService logiSysOrderSetService;

    @Override
    public LogiSysWaybillConfigVo getWaybillConfig(Long deptId) {
        // 返回对象
        LogiSysWaybillConfigVo sysWaybillConfigVo = new LogiSysWaybillConfigVo();
        // 查询运单设置信息
        LogiSysWaybillConfig sysWaybillConfig = getOne(Wrappers.lambdaQuery(LogiSysWaybillConfig.class)
                .eq(LogiSysWaybillConfig::getDeptId, deptId));
        if (ObjectUtil.isNull(sysWaybillConfig)) {
            sysWaybillConfigVo.setOutCodePrefixStatus(1);
            sysWaybillConfigVo.setOutCodePrefix("YY");
            sysWaybillConfigVo.setHideProject(0);
        } else {
            sysWaybillConfigVo.setOutCodePrefixStatus(sysWaybillConfig.getOutCodePrefixStatus());
            sysWaybillConfigVo.setOutCodePrefix(sysWaybillConfig.getOutCodePrefix());
            sysWaybillConfigVo.setHideProject(sysWaybillConfig.getHideProject());
        }
        // 查询货物保价设置信息
        sysWaybillConfigVo.setGoodsInsureConfigList(logiSysGoodsInsureConfigService.list(Wrappers.lambdaQuery(LogiSysGoodsInsureConfig.class)
                .eq(LogiSysGoodsInsureConfig::getDeptId, deptId)));
        // 查询代收服务费设置信息
        sysWaybillConfigVo.setAgentPayConfigList(logiSysAgentPayConfigService.list(Wrappers.lambdaQuery(LogiSysAgentPayConfig.class)
                .eq(LogiSysAgentPayConfig::getDeptId, deptId)));
        return sysWaybillConfigVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInfo(LogiSysWaybillConfigEditBo bo) {
        // 判断当前用户是不是超级管理员
        if (!SecurityUtils.isSysAdmin()) {
            throw new GlobalException("仅超级管理员可进行配置");
        }
        // 修改运单设置信息
        LogiSysWaybillConfig sysWaybillConfig = getOne(Wrappers.lambdaQuery(LogiSysWaybillConfig.class)
                .eq(LogiSysWaybillConfig::getDeptId, bo.getDeptId()));
        if (ObjectUtil.isNull(sysWaybillConfig)) {
            sysWaybillConfig = new LogiSysWaybillConfig();
            sysWaybillConfig.setDeptId(bo.getDeptId());
        }
        sysWaybillConfig.setOutCodePrefixStatus(bo.getOutCodePrefixStatus());
        sysWaybillConfig.setOutCodePrefix(bo.getOutCodePrefix());
        sysWaybillConfig.setHideProject(bo.getHideProject());
        saveOrUpdate(sysWaybillConfig);
        // 修改货物保价设置信息
        Map<Long, LogiSysGoodsInsureConfig> sysGoodsInsureConfigMap = bo.getGoodsInsureConfigList().stream().filter(a -> ObjectUtil.isNotNull(a.getId())).collect(Collectors.toMap(LogiSysGoodsInsureConfig::getId, Function.identity()));
        // 先整理目前需要修改或者删除的数据
        List<LogiSysGoodsInsureConfig> sysGoodsInsureConfigList = logiSysGoodsInsureConfigService.list(Wrappers.lambdaQuery(LogiSysGoodsInsureConfig.class)
                .eq(LogiSysGoodsInsureConfig::getDeptId, bo.getDeptId()));
        for (LogiSysGoodsInsureConfig goodsInsureConfig : sysGoodsInsureConfigList) {
            // 如果id存在新提交的数据中，说明是修改，如果不存在，说明是删除
            if (sysGoodsInsureConfigMap.containsKey(goodsInsureConfig.getId())) {
                BeanUtil.copyProperties(sysGoodsInsureConfigMap.get(goodsInsureConfig.getId()), goodsInsureConfig, "id", "deptId");
                logiSysGoodsInsureConfigService.updateById(goodsInsureConfig);
            } else {
                logiSysGoodsInsureConfigService.removeById(goodsInsureConfig);
            }
        }
        // 整理需要新增的数据
        List<LogiSysGoodsInsureConfig> newSysGoodsInsureConfigList = bo.getGoodsInsureConfigList().stream().filter(a -> ObjectUtil.isNull(a.getId())).map(a -> a.setDeptId(bo.getDeptId())).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(newSysGoodsInsureConfigList)) {
            logiSysGoodsInsureConfigService.saveBatch(newSysGoodsInsureConfigList);
        }
        // 修改代收服务费设置信息
        Map<Long, LogiSysAgentPayConfig> sysAgentPayConfigMap = bo.getAgentPayConfigList().stream().filter(a -> ObjectUtil.isNotNull(a.getId())).collect(Collectors.toMap(LogiSysAgentPayConfig::getId, Function.identity()));
        // 先整理目前需要修改或者删除的数据
        List<LogiSysAgentPayConfig> sysAgentPayConfigList = logiSysAgentPayConfigService.list(Wrappers.lambdaQuery(LogiSysAgentPayConfig.class)
                .eq(LogiSysAgentPayConfig::getDeptId, bo.getDeptId()));
        for (LogiSysAgentPayConfig agentPayConfig : sysAgentPayConfigList) {
            // 如果id存在新提交的数据中，说明是修改，如果不存在，说明是删除
            if (sysAgentPayConfigMap.containsKey(agentPayConfig.getId())) {
                BeanUtil.copyProperties(sysAgentPayConfigMap.get(agentPayConfig.getId()), agentPayConfig, "id", "deptId");
                logiSysAgentPayConfigService.updateById(agentPayConfig);
            } else {
                logiSysAgentPayConfigService.removeById(agentPayConfig);
            }
        }
        // 整理需要新增的数据
        List<LogiSysAgentPayConfig> newSysAgentPayConfigList = bo.getAgentPayConfigList().stream().filter(a -> ObjectUtil.isNull(a.getId())).map(a -> a.setDeptId(bo.getDeptId())).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(newSysAgentPayConfigList)) {
            logiSysAgentPayConfigService.saveBatch(newSysAgentPayConfigList);
        }
    }

    @Override
    public String getOutCode(Long deptId) {
        LogiSysWaybillConfigVo waybillConfigVo = getWaybillConfig(deptId);
        String outCodePrefix;
        if (waybillConfigVo.getOutCodePrefixStatus() == 1) {
            outCodePrefix = waybillConfigVo.getOutCodePrefix();
        } else {
            outCodePrefix = "YY";
        }
        String outCode = null;
        for (int i = 0; i < 3; i++) {
            outCode = outCodePrefix + DateUtil.format(DateUtil.date(), "yyMMdd") + RandomUtil.randomNumbers(3) + RandomUtil.randomString(2);
            if (logiWaybillService.count(Wrappers.lambdaQuery(LogiWaybill.class).eq(LogiWaybill::getOutCode, outCode)) > 0) {
                outCode = null;
            } else {
                break;
            }
        }
        if (StrUtil.isBlank(outCode)) {
            throw new GlobalException("运单号生成失败，请稍后重试");
        }
        return outCode;
//        return logiSysOrderSetService.getOutCode(deptId);
    }
}
